package br.usp.ime.ingpos.testes.modelo;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.junit.Before;
import org.junit.Test;

import br.com.caelum.vraptor.util.test.MockLocalization;
import br.usp.ime.ingpos.modelo.AreaDePesquisa;
import br.usp.ime.ingpos.modelo.Candidato;
import br.usp.ime.ingpos.modelo.CartaDeRecomendacao;
import br.usp.ime.ingpos.modelo.Curriculo;
import br.usp.ime.ingpos.modelo.DadosPessoais;
import br.usp.ime.ingpos.modelo.Inscricao;
import br.usp.ime.ingpos.modelo.Orientador;
import br.usp.ime.ingpos.modelo.PosComp;
import br.usp.ime.ingpos.modelo.ProcessoSeletivo;
import br.usp.ime.ingpos.modelo.Usuario;
import br.usp.ime.ingpos.modelo.dao.AreaDePesquisaDAO;
import br.usp.ime.ingpos.modelo.dao.InscricaoDAO;
import br.usp.ime.ingpos.modelo.dao.OrientadorDAO;
import br.usp.ime.ingpos.modelo.dao.PerfilDao;
import br.usp.ime.ingpos.modelo.dao.ProcessoSeletivoDao;
import br.usp.ime.ingpos.modelo.dao.UsuarioDao;
import br.usp.ime.ingpos.services.AreaDePesquisaService;
import br.usp.ime.ingpos.services.EmailService;
import br.usp.ime.ingpos.services.OrientadorService;
import br.usp.ime.ingpos.services.ProcessoSeletivoService;
import br.usp.ime.ingpos.testes.BancoDeDadosTestCase;
import br.usp.ime.ingpos.testes.services.RegistroNovoUsuarioServiceTeste;

public class InscricaoTeste extends BancoDeDadosTestCase {
	public InscricaoTeste(String name) {
		super(name);
	}

	private Candidato[] candidatos;
	private EmailService emailService;
	private Candidato candidato;
	private Candidato candidato2;
	private Orientador orientador;
	private List<AreaDePesquisa> areasDeAfinidade;
	private Set<CartaDeRecomendacao> cartasDeRecomendacao;
	private Inscricao inscricao;
	private InscricaoDAO inscricaoDao;
	private ProcessoSeletivo processoSeletivo;

	@Before
	protected void setUp() throws Exception {
		super.setUp();

		Usuario usuario;

		candidatos = new Candidato[10];
		final UsuarioDao usuarioDao = new UsuarioDao(getSessionCreator());
		final ProcessoSeletivoService processoSeletivoService = new ProcessoSeletivoService(
		    new ProcessoSeletivoDao( getSessionCreator() ), emailService, new MockLocalization());
		assertNotNull(processoSeletivoService);
		List<ProcessoSeletivo> processosSeletivos = processoSeletivoService
				.buscarProcessosSeletivosPorData(new Date());
		assertFalse(processosSeletivos.isEmpty());
		processoSeletivo = processosSeletivos.get(0);

		inscricaoDao = new InscricaoDAO(getSessionCreator());

		usuario = usuarioDao
				.procurarPorEmail(RegistroNovoUsuarioServiceTeste.EMAIL);
		assertNotNull(usuario);
		candidato = (Candidato) usuario;
		assertNotNull(candidato);

		usuario = usuarioDao
				.procurarPorEmail(RegistroNovoUsuarioServiceTeste.EMAIL2);
		assertNotNull(usuario);
		candidato2 = (Candidato) usuario;
		assertNotNull(candidato);

		for (int i = 0; i < 10; i++) {
			StringBuilder email = new StringBuilder("aluno").append(i).append(
					"@ime.usp.br");

			StringBuilder nome = new StringBuilder("Aluno ").append(i);

			usuario = usuarioDao.procurarPorEmail(email.toString());
			assertNotNull(usuario);

			if (usuario.getDadosPessoais() == null) {
				DadosPessoais d = new DadosPessoais();
				d.setNomeCompleto(nome.toString());
				usuario.setDadosPessoais(d);
			}

			candidatos[i] = (Candidato) usuario;
			assertNotNull(candidatos[i]);

			if (candidatos[i].getCurriculo() == null) {
				candidatos[i].setCurriculo(new Curriculo());
			}

			if (candidatos[i].getCurriculo().getPosComp() == null) {
				PosComp pc = new PosComp();
				pc.setNotaLogica(i * 10);
				pc.setNotaMatematica(i * 10);
				pc.setNotaTecnologia(i * 10);
				candidatos[i].getCurriculo().setPosComp(pc);
				testPosCompDaInscricao(candidatos[i]);

			}
		}
		final AreaDePesquisaDAO areaDePesquisaDao = new AreaDePesquisaDAO(
				getSessionCreator());
		final AreaDePesquisaService areaDePesquisaService = new AreaDePesquisaService(
				areaDePesquisaDao);
		areasDeAfinidade = areaDePesquisaService.procurarTodasAreasDePesquisa();
		assertNotNull(areasDeAfinidade);

		final OrientadorDAO orientadorDao = new OrientadorDAO(
				getSessionCreator());
		orientador = orientadorDao.findAll().get(0);
		assertNotNull(orientador);
	}

	private void testPosCompDaInscricao(Candidato candidatoPosComp) {
		assertNotNull(candidatoPosComp.getCurriculo().getPosComp());
	}

	@Test
	public void testCriarOuAtualizarInscricao() {
		criaOuAtualizaInscricao(candidato);
		criaOuAtualizaInscricao(candidato2);

		inscricao = inscricaoDao.procurarPorCandidatoEProcessoSeletivo(
				candidato2, processoSeletivo);

		assertNotNull(inscricao.getInscricaoID());
		inscricao.setInscricaoID(inscricao.getInscricaoID());

		inscricao.setOutrosProcessosSeletivos("Outro Processo Seletivo");
		assertEquals("Outro Processo Seletivo",
				inscricao.getOutrosProcessosSeletivos());

		inscricao.setOrientadorDesejado(orientador);
		assertNotNull(inscricao.getOrientadorDesejado());

		inscricao.setDedicacaoExclusiva("Sim");
		assertEquals("Sim", inscricao.getDedicacaoExclusiva());

		inscricao.setAreasDeInteresseAfinidade1(areasDeAfinidade);
		assertNotNull(inscricao.getAreasDeInteresseAfinidade1());

		inscricao.setAreasDeInteresseAfinidade2(areasDeAfinidade);
		assertNotNull(inscricao.getAreasDeInteresseAfinidade2());

		inscricao.setAreasDeInteresseAfinidade3(areasDeAfinidade);
		assertNotNull(inscricao.getAreasDeInteresseAfinidade3());

		inscricao.setExposicaoPropositos("Propositos");
		assertEquals("Propositos", inscricao.getExposicaoPropositos());

		inscricao.setExposicaoPropositos("Propositos");
		assertEquals("Propositos", inscricao.getExposicaoPropositos());

		inscricao.setObservacoes("Observacoes");
		assertEquals("Observacoes", inscricao.getObservacoes());

		inscricao.setSabeAreasDeInteresse(true);
		assertEquals(true, inscricao.isSabeAreasDeInteresse());

		inscricao.setAprovado(true);
		assertEquals(true, inscricao.isAprovado());

		inscricao.setConversouComCoordenador(true);
		assertEquals(true, inscricao.isConversouComCoordenador());

		assertEquals(false, inscricao.isInteresse());

		assertNotNull(inscricao.getSerialversionuid());

		for (int i = 0; i < 10; i++) {
			criaOuAtualizaInscricao(candidatos[i]);
		}
	}

	@Test
	public void testInscricoesIguais() {
		Inscricao inscricao1;
		Inscricao inscricao2;

		inscricao1 = inscricaoDao.procurarPorCandidatoEProcessoSeletivo(
				candidato, processoSeletivo);
		inscricao2 = inscricaoDao.procurarPorCandidatoEProcessoSeletivo(
				candidato, processoSeletivo);

		inscricao1.equals(inscricao2);

		inscricao2 = inscricaoDao.procurarPorCandidatoEProcessoSeletivo(
				candidato2, processoSeletivo);

		inscricao1.equals(inscricao2);

		inscricao1.equals(candidato);

	}

	private void criaOuAtualizaInscricao(Candidato candidato) {
		inscricao = inscricaoDao.procurarPorCandidatoEProcessoSeletivo(
				candidato, processoSeletivo);
		if (inscricao == null) {
			inscricao = new Inscricao();
		}

		inscricao.setCandidato(candidato);
		assertNotNull(inscricao.getCandidato());

		inscricao.setProcessoSeletivo(processoSeletivo);
		assertNotNull(inscricao.getProcessoSeletivo());

		if (candidato.getUsuarioID() % 2 == 0)
			inscricao.setAprovado(true);

		inscricaoDao.saveOrUpdate(inscricao);

	}

	@Test
	public void testProcurarPorHash() {
		inscricao = inscricaoDao.procurarPorCandidato(candidato);
		assertTrue(inscricao != null);

		inscricao = inscricaoDao.procurarPorCandidato(candidato2);
		assertTrue(inscricao != null);

		for (int i = 0; i < 10; i++) {
			inscricao = inscricaoDao.procurarPorCandidato(candidatos[i]);
			assertTrue(inscricao != null);
		}
	}

}
